use crate::generators;
use crate::processor;

/// Generator to generate semi-formatted text using ansi escape sequences.
pub struct AnsiGenerator {
    header_count: usize,
}

impl AnsiGenerator {
    /// Creates a new ansi generator.
    pub fn new() -> AnsiGenerator {
        AnsiGenerator { header_count: 0 }
    }
}

impl generators::Generator for AnsiGenerator {
    /// Formats a token as with ANSI escape codes,
    /// These codes can be printed out into most terminals.
    ///
    /// # Example
    /// ```rust
    /// use apollon::generators::{Generator, AnsiGenerator};
    /// use apollon::processor;
    ///
    /// let mut generator = AnsiGenerator::new(); // needs to be mut to generate
    /// let bold_text = processor::DocToken::Bold(String::from("Hello, World!"));
    ///
    /// // prints 'Hello, World!' in bold
    /// println!("{}", generator.format_token(&bold_text))
    /// ```
    fn format_token(&mut self, token: &processor::DocToken) -> String {
        match token {
            processor::DocToken::Title(content) => format!("\t\t\x1b[1m{content}\x1b[0m\n\n"),
            processor::DocToken::Author(content) => format!("\t\t\x1b[3m{content}\x1b[0m\n"),
            processor::DocToken::Date(content) => format!("\t\t\x1b[0m{content}\n"),

            processor::DocToken::Comment => String::new(),
            processor::DocToken::Newline => String::from("\n"),

            processor::DocToken::NHeader(content) => {
                self.header_count += 1;
                format!("\t\x1b[1m{}. {content}\x1b[0m\n", self.header_count)
            }
            processor::DocToken::Header(content) => format!("\t\x1b[1m{content}\x1b[0m\n"),

            processor::DocToken::Bold(content) => format!("\x1b[1m{content}\x1b[0m "),
            processor::DocToken::Italic(content) => format!("\x1b[3m{content}\x1b[0m "),
            processor::DocToken::BoldItalic(content) => format!("\x1b[1;3m{content}\x1b[0m"),

            processor::DocToken::Text(content) => format!("{content} "),
        }
    }
}
